/*
 * Copyright 2010-2012 Susanta Tewari. <freecode4susant@users.sourceforge.net>
 *
 * This program is free software: you can redistribute it and/or modify
 * it under the terms of the GNU General Public License as published by
 * the Free Software Foundation, either version 3 of the License, or
 * (at your option) any later version.
 *
 * This program is distributed in the hope that it will be useful,
 * but WITHOUT ANY WARRANTY; without even the implied warranty of
 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
 * GNU General Public License for more details.
 *
 * You should have received a copy of the GNU General Public License
 * along with this program.  If not, see <http://www.gnu.org/licenses/>.
 */

package commons.util;

import com.google.common.base.Function;
import com.google.common.base.Joiner;
import com.google.common.collect.Collections2;
import commons.util.base.TwoWayConverter;

import java.awt.*;
import java.text.DecimalFormat;
import java.util.ArrayList;
import java.util.List;

import static commons.util.ListUtil.toList;
import static java.lang.Double.parseDouble;

/**
 * @author Susanta Tewari
 * @version version
 * @history Created on 12/13/13.
 * @since since
 */
public class TwoWayConverterS {

    public static TwoWayConverter<String, double[]> ofDouble(final String delim) {

        final DecimalFormat fmt = new DecimalFormat("0.####");

        return new TwoWayConverter<String, double[]>() {

            @Override
            public double[] fwd(String input) {

                final String[] tokens = input.split(delim);
                double[] result       = new double[tokens.length];

                for (int i = 0; i < tokens.length; i++) {
                    result[i] = parseDouble(tokens[i]);
                }

                return result;
            }
            @Override
            public String bck(double[] output) {

                return Joiner.on(delim).join(
                    Collections2.transform(
                        ListUtil.<Double>toList(output), new Function<Double, String>() {

                    @Override
                    public String apply(Double input) {
                        return fmt.format(input);
                    }

                }));
            }
        };
    }

    public static TwoWayConverter<String, int[]> ofInt(final String delim) {

        return new TwoWayConverter<String, int[]>() {

            @Override
            public int[] fwd(String input) {

                final String[] tokens = input.split(delim);
                int[] result          = new int[tokens.length];

                for (int i = 0; i < tokens.length; i++) {
                    result[i] = Integer.parseInt(tokens[i]);
                }

                return result;
            }
            @Override
            public String bck(int[] output) {
                return Joiner.on(delim).join(toList(output));
            }
        };
    }

    public static <T> TwoWayConverter<String, List<T>> of_String_List(final String delim,
            final TwoWayConverter<String, T> cnv) {

        return new TwoWayConverter<String, List<T>>() {

            @Override
            public List<T> fwd(String input) {

                final String[] tokens = input.split(delim);
                List<T> result        = new ArrayList<>(tokens.length);

                for (String token : tokens) {
                    result.add(cnv.fwd(token));
                }

                return result;
            }
            @Override
            public String bck(List<T> output) {
                return Joiner.on(delim).join(output);
            }
        };
    }

    /**
     * Input format: r,g,b (, is the delim specified)
     * @param delim
     * @return
     */
    public static TwoWayConverter<String, Color> ofColor(final String delim) {

        return new TwoWayConverter<String, Color>() {

            @Override
            public Color fwd(String input) {

                final String[] rgb = input.split(",");

                ExceptionUtil.throwArgEx(rgb.length != 3, "invalid RGB format : " + input);

                int r = Integer.parseInt(rgb[0]);
                int g = Integer.parseInt(rgb[1]);
                int b = Integer.parseInt(rgb[2]);

                return new Color(r, g, b);
            }
            @Override
            public String bck(Color output) {

                int r = output.getRed();
                int g = output.getGreen();
                int b = output.getBlue();

                return Joiner.on(delim).join(r, g, b);
            }
        };
    }

    public static TwoWayConverter<String, String> ofString() {

        return new TwoWayConverter<String, String>() {

            @Override
            public String fwd(String input) {
                return input;
            }
            @Override
            public String bck(String output) {
                return output;
            }
        };
    }
}
